package com.github.baichuan.application.scaffold.rest.domain.application;

import com.github.baichuan.application.scaffold.rest.jpa.application.ApplicationRepository;
import com.github.baichuan.application.scaffold.rest.dto.application.ApplicationForm;
import com.github.baichuan.web.dto.Result;
import com.github.baichuan.web.error.NoSuchEntityException;
import com.github.baichuan.utils.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Service
@Transactional(rollbackFor = Exception.class)
public class ApplicationService {

    @Autowired
    private ApplicationRepository applicationRepository;
    @Autowired
    private RealmService realmService;
    @Autowired
    private SnowFlake snowFlake;


    public Application find(String id){
        return applicationRepository.findById(id).orElseThrow(() -> new NoSuchEntityException("应用id错误"));
    }

    public Application findByCode(String code){
        return applicationRepository.findByCode(code).orElseThrow(() -> new NoSuchEntityException("应用代码" + code + "错误"));
    }

    public List<Application> findByRealm(Realm realm) {
        return applicationRepository.findByRealm(realm);
    }

    public Page<Application> query(Specification<Application> specification, Pageable pageable){
        return applicationRepository.findAll(specification, pageable);
    }

    public List<Application> findAll() {
        return applicationRepository.findAll();
    }

    public Result add(ApplicationForm form) {
        if (applicationRepository.findByName(form.getName()).isPresent()) {
            return Result.fail("应用名称重复");
        }
        if(applicationRepository.findByCode(form.getCode()).isPresent()){
            return Result.fail("应用代码重复");
        }
        Application application = new Application();
        application.setId(snowFlake.nextBase62Id().substring(6));
        merge(form, application);

        applicationRepository.save(application);
        return Result.success("应用添加成功", application.getId());
    }

    private void merge(ApplicationForm form, Application application) {
        application.setName(form.getName().trim());
        application.setCode(form.getCode().trim());
        application.setTenant(form.getTenant());
        application.setRealm(realmService.find(form.getRealmId()));
    }

    public Result edit(String id, ApplicationForm form) {
        Optional<Application> duplicationName = applicationRepository.findByName(form.getName());
        if(duplicationName.isPresent() && !duplicationName.get().getId().equals(id)){
            return Result.fail("应用代码重复");
        }

        Optional<Application> duplicationCode = applicationRepository.findByCode(form.getCode());
        if(duplicationCode.isPresent() && !duplicationCode.get().getId().equals(id)){
            return Result.fail("应用代码重复");
        }

        Optional<Application> applicationOptional = applicationRepository.findById(id);
        if (!applicationOptional.isPresent()) {
            return Result.fail("应用不存在");
        }

        Application application = applicationOptional.get();
        merge(form, application);

        applicationRepository.save(application);
        return Result.success("应用保存成功");
    }

    public Result remove(String id) {
        Optional<Application> applicationOptional = applicationRepository.findById(id);
        if (!applicationOptional.isPresent()) {
            return Result.fail("应用不存在");
        }

        Application application = applicationOptional.get();
        applicationRepository.delete(application);
        return Result.success("应用删除成功");
    }
}
